﻿<%@ WebHandler Language="C#" Class="ContainerInfoFollowPrintHandler" %>

using System;
using System.Web;
using System.Collections.Generic;
using System.Web.Script.Serialization;
using System.Linq;
using BusinessRule.Business;
using System.Data;
using Newtonsoft.Json;
using System.IO;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.HSSF.UserModel;
using System.Collections;
using BusinessRule.DTO;
using System.Web.SessionState;
using BusinessRule.BusinessFactory;
using BusinessRule.IBusiness;
using DatabaseAccess.DBUtility;
using System.Text;
using QRCoder;
using System.Drawing;

/*Description: 批次随件卡打印
'Copyright (c) : 通力凯顿（北京）系统集成有限公司
'Writer: Zhangrj 
'create Date:2023-6-16
'Rewriter:
'Rewrite Date:
*/
public class ContainerInfoFollowPrintHandler : IHttpHandler, IRequiresSessionState
{
    CurrentUserInfo m_UserInfo;
    DataTable dtMain = new DataTable();//批次主数据
    DataTable dtChildContainer = new DataTable();//批次子序号信息
    DataTable dtAttr = new DataTable();//批次属性
    DataTable dtWorkflowStep = new DataTable();//批次在制工艺下的工序信息
    DataTable dtStepAttr = new DataTable();//批次工序备注信息
    StringBuilder html = new StringBuilder();//最终的html打印样式
    int pageHeight = 0;//页高
    public void ProcessRequest(HttpContext context)
    {
        try
        {
            m_UserInfo = (CurrentUserInfo)context.Session["CurrentUserInfo"];
            //if (m_UserInfo == null)
            //{
            //    context.Response.Write(JsonConvert.SerializeObject(new uMESProcessResult() { Result = false, Message = "数据过期，请重新登录" }));
            //    return;
            //}
            var action = context.Request["action"].ToString();
            switch (action)
            {
                case "GetPage": //随件卡打印
                    GetPage(context);
                    break;
                case "GetPageByCover": //只打印随件卡封面，适用于标签纸张打印
                    GetPageByCover(context);
                    break;
                case "GetPageByTag": //随件卡标签打印
                    GetPageByTag(context);
                    break;
                default:
                    break;
            }
        }
        catch (Exception ex)
        {
            var result = new uMESProcessResult();
            result.Result = false;
            result.Message = ex.Message;
            context.Response.ContentType = "text/html";
            context.Response.Write(JsonConvert.SerializeObject(result));
        }
    }

    /// <summary>
    /// 随件卡标签打印
    /// </summary>
    /// <param name="context"></param>
    public void GetPageByTag(HttpContext context)
    {
        List<Dictionary<string, string>> printParams = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(Encoding.Unicode.GetString(Convert.FromBase64String(context.Request["printParams"].ToString())));
        if (printParams != null && printParams.Count > 0)
        {
            for (int i = 0; i < printParams.Count; i++)
            {
                if (GetPageData(printParams[i]))
                {
                    if (i > 0 && !string.IsNullOrWhiteSpace(html.ToString()))
                    {
                        html.AppendLine(GetPaging());//分页
                    }
                    BindHtmlByTag(); //追加HTML页面内容
                }
            }
        }
        context.Response.Write(JsonConvert.SerializeObject(new uMESProcessResult() { Message = "获取成功", Result = true, ReturnData = html.ToString() }));
    }

    /// <summary>
    /// 只打印随件卡封面，适用于标签纸张打印
    /// </summary>
    /// <param name="context"></param>
    public void GetPageByCover(HttpContext context)
    {
        List<Dictionary<string, string>> printParams = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(Encoding.Unicode.GetString(Convert.FromBase64String(context.Request["printParams"].ToString())));
        if (printParams != null && printParams.Count > 0)
        {
            for (int i = 0; i < printParams.Count; i++)
            {
                if (GetPageData(printParams[i]))
                {
                    if (i > 0 && !string.IsNullOrWhiteSpace(html.ToString()))
                    {
                        html.AppendLine(GetPaging());//分页
                    }
                    GetPageHtml(true);
                }
            }
        }
        context.Response.Write(JsonConvert.SerializeObject(new uMESProcessResult() { Message = "获取成功", Result = true, ReturnData = html.ToString() }));
    }

    /// <summary>
    /// 随件卡打印
    /// </summary>
    /// <param name="context"></param>
    public void GetPage(HttpContext context)
    {
        List<Dictionary<string, string>> printSession = (List<Dictionary<string, string>>)context.Session["PrintInfo"];
        context.Session.Remove("PrintInfo");
        if (printSession != null && printSession.Count > 0)
        {
            for (int i = 0; i < printSession.Count; i++)
            {
                if (GetPageData(printSession[i]))
                {
                    //if (i != 0 && i % 2 == 0) //两张随件卡打印在一页上
                    //{
                    //    strHtml += GetPaging();//分页
                    //}
                    if (i > 0 && !string.IsNullOrWhiteSpace(html.ToString()))
                    {
                        html.AppendLine(GetPaging());//分页
                    }
                    GetPageHtml();
                }
            }
        }
        else
        {
            string ContainerId = context.Request["ContainerId"];
            string WorkflowId = context.Request["WorkflowId"];
            if (string.IsNullOrEmpty(ContainerId) || string.IsNullOrEmpty(WorkflowId))
            {
                context.Response.Write(JsonConvert.SerializeObject(new uMESProcessResult() { Message = "刷新无效，请关闭后重新打印", Result = false }));
                return;
            }
            Dictionary<string, string> printInfo = new Dictionary<string, string>();
            printInfo["ContainerId"] = ContainerId;
            printInfo["WorkflowId"] = WorkflowId;
            if (GetPageData(printInfo))
            {
                GetPageHtml();
            }
        }
        context.Response.Write(JsonConvert.SerializeObject(new uMESProcessResult() { Message = "获取成功", Result = true, ReturnData = html.ToString() }));
    }

    /// <summary>
    /// 获取数据
    /// </summary>
    /// <param name="dic"></param>
    /// <returns></returns>
    private bool GetPageData(Dictionary<string, string> dic)
    {
        InitDataObj();
        /*获取批次信息*/
        string sql = string.Format(@"SELECT c.mfgordername,m.lgort,c.productname,c.productdescription,c.containername,c.containertype,
                       p.charactertype,cc.originalstartdate,c.qty,cc.containercomments,p.materialtrademark,c.containerid,
                       p.materialspecification,c.isselfmfg,f.factoryname,wc.workcentername
                       FROM containercurrentinfo c
                       LEFT JOIN mfgorder m ON m.mfgordername = c.mfgordername 
                       LEFT JOIN container cc ON cc.containerid = c.containerid
                       LEFT JOIN product p ON p.productid = c.productid
                       LEFT JOIN factory f ON f.factoryid = c.originalfactoryid
                       LEFT JOIN Workcenter wc ON wc.workcenterid = c.workcenterid
                       WHERE c.containerid = '{0}'", dic["ContainerId"].ToString());
        dtMain = DatabaseHelper.Query_ReturnDatTable(sql);
        if (dtMain.Rows.Count == 0)
        {
            return false;
        }
        /* 获取批次属性信息*/
        sql = string.Format(@"SELECT u.attributevalue,u.userattributename FROM userattribute u WHERE u.parentid = '{0}'", dic["ContainerId"].ToString());
        dtAttr = DatabaseHelper.Query_ReturnDatTable(sql);
        /* 获取批次子序号信息*/
        if (dtMain.Rows[0]["containertype"].ToString() == "3")
        {
            sql = string.Format(@"SELECT c.containerid,c.containername,c.qty,c.status,REPLACE(c.containername,cc.togetherflag,'') childContainerNo 
                                FROM container c
                                LEFT JOIN container cc ON cc.containerid = c.parentcontainerid
                                WHERE c.parentcontainerid = '{0}'", dic["ContainerId"].ToString());
            dtChildContainer = DatabaseHelper.Query_ReturnDatTable(sql);
        }
        /* 获取批次的工序信息*/
        sql = string.Format(@"SELECT ws.workflowstepname FROM workflowstep ws WHERE ws.workflowid = '{0}' ORDER BY ws.sequence", dic["WorkflowId"].ToString());
        dtWorkflowStep = DatabaseHelper.Query_ReturnDatTable(sql);
        /* 获取批次的工序备注信息*/
        sql = string.Format(@"SELECT a.notes,ws.workflowstepid,ws.workflowstepname FROM containerstepattribute a 
                            LEFT JOIN workflowstep ws ON ws.workflowstepid = a.workflowstepid
                            WHERE a.containerid = '{0}'", dic["ContainerId"].ToString());
        dtStepAttr = DatabaseHelper.Query_ReturnDatTable(sql);
        return true;
    }

    /// <summary>
    /// 获取页面打印HTML
    /// </summary>
    /// <param name="isCover">是否只打印封面</param>
    private void GetPageHtml(bool isOnlyCover = false)
    {
        /*绑定批次表头信息*/
        BindContainerRecordHtml();
        /*分页*/
        //html.AppendLine(GetPaging());
        if (!isOnlyCover)
        {
            /*绑定质量记录卡信息*/
            BindQualityRecordHtml();
        }
        /*绑定工序记录卡信息*/
        //BindWorkflowStepHtml();
    }

    /// <summary>
    /// 获取随件卡批次表头信息
    /// </summary>
    private void BindContainerRecordHtml()
    {
        DataRow dr = dtMain.Rows[0];
        html.AppendLine("<div><span style='float:left;font-size:20px;'>公开</span></div><div><label class='headTitle'>随件卡</label></div>");
        html.AppendLine("<div style='text-align:right'>HF.13460W3032(V3.0)</div>");//add by longb 2024-10-24
        html.AppendLine("<table class='productWorkingTable'>");
        html.AppendFormat("<tr><td style='width:120px;'>标识</td><td>{0}</td>", dr["charactertype"].ToString());
        html.AppendFormat("<td colspan='2'>开卡日期</td><td colspan='2' style='width:100px;'>{0}</td></tr>", DateTime.Parse(dr["originalstartdate"].ToString()).ToString("yyyy-MM-dd"));
        html.AppendFormat("<tr><td>订单号</td><td>{0}</td>", dr["mfgordername"].ToString());
        html.AppendFormat("<td rowspan='4' colspan='4'><img src='data:image/Jpeg;base64,{0}'></td></tr>", CreateQRCodeImg(dr["ContainerId"].ToString()));//批次ID二维码显示
        html.AppendFormat("<tr><td>零件号/批次</td><td>{0}</td></tr>", dr["containername"].ToString());
        html.AppendFormat("<tr><td>库存地点</td><td>{0}</td></tr>", dr["lgort"].ToString());

        DataRow attrValue = dtAttr.Select("userattributename='实发数/顺序号'").FirstOrDefault();
        html.AppendFormat("<tr><td>实发数/顺序号</td><td>{0}</td></tr>", attrValue == null ? "<div class='takeLine'></div>" : attrValue["attributevalue"].ToString());

        html.AppendFormat("<tr><td>生产厂</td><td>{0}</td>", dr["factoryname"].ToString() + dr["workcentername"].ToString());

        attrValue = dtAttr.Select("userattributename='熔炉号母'").FirstOrDefault();
        html.AppendFormat("<td colspan='2'>熔炉号</td><td colspan='2'>{0}</td></tr>", attrValue == null ? "<div class='takeLine'></div>" : attrValue["attributevalue"].ToString());

        html.AppendFormat("<tr><td>零件名</td><td>{0}</td>", dr["productdescription"].ToString());
        html.AppendFormat("<td colspan='2'>材料牌号及规格</td><td colspan='2'>{0}</td></tr>", dr["materialtrademark"].ToString() + "/" + dr["materialspecification"].ToString());

        attrValue = dtAttr.Select("userattributename='平行作业单号'").FirstOrDefault();
        html.AppendFormat("<tr><td>例外放行单号</td><td>{0}</td>", attrValue == null || string.IsNullOrWhiteSpace(attrValue["attributevalue"].ToString()) ? "<div class='takeLine'></div>" : attrValue["attributevalue"].ToString());

        attrValue = dtAttr.Select("userattributename='供应商'").FirstOrDefault();
        html.AppendFormat("<td colspan='2'>供应商</td><td colspan='2'>{0}</td></tr>", attrValue == null || string.IsNullOrWhiteSpace(attrValue["attributevalue"].ToString()) ? "<div class='takeLine'></div>" : attrValue["attributevalue"].ToString());

        string notes = string.Empty;//备注
        if (dr["isselfmfg"].ToString() == "0")
        {
            DataRow[] drs = dtStepAttr.Select(string.Format("workflowstepname='{0}'", dtWorkflowStep.Rows[0]["workflowstepname"].ToString()));//取第一个序的备注信息
            if (drs.Length > 0)
            {
                //notes += string.Format("第一工序：{0}的备注：", dtWorkflowStep.Rows[0]["workflowstepname"].ToString());
                foreach (DataRow item in drs)
                {
                    notes += item["notes"].ToString();
                }
            }
        }
        if (!string.IsNullOrWhiteSpace(dr["containercomments"].ToString()))
        {
            notes += string.IsNullOrWhiteSpace(notes) ? "批次备注：" + dr["containercomments"].ToString() : "；批次备注：" + dr["containercomments"].ToString();
        }
        html.AppendFormat("<tr><td>备注</td><td>{0}</td>", string.IsNullOrWhiteSpace(notes) ? "<div class='takeLine'></div>" : notes);
        html.AppendFormat("<td>计划数</td><td>{0}</td><td>实发数</td><td>{0}</td></tr></table>", dr["qty"].ToString());
        /*绑定条形码*/
        html.AppendFormat("<div style='height:70px;display:none'><div class=barCode style='float:Left'>*{0}*</div> <div class=barCode style='float:Right'>*{1}*</div><div style='clear:both'></div></div>", dr["ContainerId"].ToString(), dr["mfgordername"].ToString());
    }

    /// <summary>
    /// 绑定随件卡标签打印样式
    /// </summary>
    private void BindHtmlByTag()
    {
        DataRow dr = dtMain.Rows[0];
        html.AppendLine("<div><span style='float:left;font-size:20px;'>公开</span></div><div><label class='headTitle'>随件卡标签</label></div>");
        html.AppendLine("<table class='productWorkingTable'>");
        html.AppendFormat("<tr><td>订单号</td><td>{0}</td>", dr["mfgordername"].ToString());
        html.AppendFormat("<td rowspan='3' colspan='2'><img src='data:image/Jpeg;base64,{0}'></td></tr>", CreateQRCodeImg(dr["ContainerId"].ToString()));//批次ID二维码显示
        html.AppendFormat("<tr><td>零件号</td><td>{0}</td></tr>", dr["productname"].ToString());
        html.AppendFormat("<tr><td>零件名称</td><td>{0}</td></tr>", dr["productdescription"].ToString());
        html.AppendFormat("<tr><td>生产单位</td><td>{0}</td>", dr["factoryname"].ToString());
        html.AppendFormat("<td>在制数</td><td>{0}</td></tr>", dr["qty"].ToString());

        DataRow attrValue = dtAttr.Select("userattributename='实发数/顺序号'").FirstOrDefault();
        attrValue = dtAttr.Select("userattributename='熔炉号母'").FirstOrDefault();
        html.AppendFormat("<tr><td>熔炉号</td><td>{0}</td>", attrValue == null ? "<div class='takeLine'></div>" : attrValue["attributevalue"].ToString());
        html.AppendFormat("<td>批次号</td><td>{0}</td></tr>", dr["containername"].ToString().Replace(dr["productname"].ToString() + "/", ""));

        html.AppendFormat("<tr><td>库存地点</td><td>{0}</td>", dr["lgort"].ToString());
        html.AppendFormat("<td>材料牌号</td><td>{0}</td></tr>", dr["materialtrademark"].ToString());

        attrValue = dtAttr.Select("userattributename='平行作业单号'").FirstOrDefault();
        html.AppendFormat("<tr><td>例外放行单号</td><td>{0}</td>", attrValue == null || string.IsNullOrWhiteSpace(attrValue["attributevalue"].ToString()) ? "<div class='takeLine'></div>" : attrValue["attributevalue"].ToString());

        attrValue = dtAttr.Select("userattributename='平行作业工序'").FirstOrDefault();
        html.AppendFormat("<td>终止工序</td><td>{0}</td></tr>", attrValue == null || string.IsNullOrWhiteSpace(attrValue["attributevalue"].ToString()) ? "<div class='takeLine'></div>" : attrValue["attributevalue"].ToString());

        string notes = string.Empty;//备注
        if (dr["isselfmfg"].ToString() == "0")
        {
            DataRow[] drs = dtStepAttr.Select(string.Format("workflowstepname='{0}'", dtWorkflowStep.Rows[0]["workflowstepname"].ToString()));//取第一个序的备注信息
            if (drs.Length > 0)
            {
                //notes += string.Format("第一工序：{0}的备注：", dtWorkflowStep.Rows[0]["workflowstepname"].ToString());
                foreach (DataRow item in drs)
                {
                    notes += item["notes"].ToString();
                }
            }
        }
        if (!string.IsNullOrWhiteSpace(dr["containercomments"].ToString()))
        {
            notes += string.IsNullOrWhiteSpace(notes) ? "批次备注：" + dr["containercomments"].ToString() : "；批次备注：" + dr["containercomments"].ToString();
        }
        html.AppendFormat("<tr><td>备注</td><td>{0}</td>", string.IsNullOrWhiteSpace(notes) ? "<div class='takeLine'></div>" : notes);
        html.AppendFormat("<td>标识</td><td>{0}</td></tr></table>", dr["charactertype"].ToString());
    }

    /// <summary>
    /// 绑定质量记录卡
    /// </summary>
    private void BindQualityRecordHtml()
    {
        if (dtChildContainer.Rows.Count == 0)
        {
            return;
        }
        int outNum = 0;
        if (dtChildContainer.AsEnumerable().Where(p => int.TryParse(p["childContainerNo"].ToString(), out outNum) == false).Count() == 0) //判断子序号是否为数字
        {
            dtChildContainer = dtChildContainer.AsEnumerable().OrderBy(p => int.Parse(p["childContainerNo"].ToString())).CopyToDataTable();//排序
        }
        html.AppendLine("<table class='stepInfoTable'><tr><td colspan='10' class='headTitle' style='font-size:20px'>质量记录卡</td></tr>");
        double db = (double)dtChildContainer.Rows.Count / 10;
        int rows = (int)Math.Ceiling(db);//每行显示10个子序号
        int max = 0;
        for (int i = 0; i < rows; i++)
        {
            max = 0;
            html.AppendLine("<tr>");
            while (max < 10)
            {
                int ix = (i * 10) + max;
                html.AppendFormat("<td style='width:80px'>{0}</td>", ix < dtChildContainer.Rows.Count ? dtChildContainer.Rows[ix]["childContainerNo"].ToString() : "");
                max++;
            }
            html.AppendLine("</tr>");
        }
        html.AppendLine("</table>");
    }

    /// <summary>
    /// 绑定工序信息
    /// </summary>
    private void BindWorkflowStepHtml()
    {
        if (dtWorkflowStep.Rows.Count == 0)
        {
            return;
        }
        pageHeight = 40;
        html.AppendLine("<table class='stepInfoTable'><tr><td colspan='5' class='headTitle' style='font-size:13px'>工序记录卡</td></tr>");
        int rows = (int)Math.Ceiling((double)dtWorkflowStep.Rows.Count / 5);//每行显示5个工序
        int max = 0;
        for (int i = 0; i < rows; i++)
        {
            if (pageHeight + 30 > 1000)
            {
                html.AppendLine(GetPaging());//分页
                pageHeight = 40;
            }
            max = 0;
            html.AppendLine("<tr>");
            while (max < 5)
            {
                int ix = (i * 5) + max;
                html.AppendFormat("<td style='width:160px'>{0}</td>", ix < dtWorkflowStep.Rows.Count ? dtWorkflowStep.Rows[ix]["workflowstepname"].ToString() : "");
                max++;
            }
            html.AppendLine("</tr>");
            pageHeight += 30;
        }
        html.AppendLine("</table>");
    }

    /// <summary>
    /// 生成二维码
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    protected string CreateQRCodeImg(string str)
    {
        QRCoder.QRCodeGenerator qrGenerator = new QRCodeGenerator();

        QRCodeData qrCodeData = qrGenerator.CreateQrCode(str, QRCodeGenerator.ECCLevel.L);
        QRCode qrcode = new QRCode(qrCodeData);

        Bitmap qrCodeImage = qrcode.GetGraphic(6, Color.Black, Color.White, null, 5, 1, false);
        MemoryStream ms = new MemoryStream();
        qrCodeImage.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);

        return Convert.ToBase64String(ms.ToArray());
    }

    /// <summary>
    /// 获取分页
    /// </summary>
    /// <returns></returns>
    private string GetPaging()
    {
        return "<div class='paging'></div>";
    }

    /// <summary>
    /// 初始化数据对象
    /// </summary>
    private void InitDataObj()
    {
        dtMain.Clear();
        dtChildContainer.Clear();
        dtAttr.Clear();
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

}